package com.ukefu.webim.web.handler.apps.xiaoe;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.apache.commons.io.FileUtils;
import org.elasticsearch.common.lang3.StringUtils;
import org.jsoup.helper.StringUtil;
import org.lionsoul.jcseg.tokenizer.core.JcsegException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.ukefu.core.UKDataContext;
import com.ukefu.util.Menu;
import com.ukefu.util.UKTools;
import com.ukefu.util.ai.AiUtils;
import com.ukefu.util.ai.DicSegment;
import com.ukefu.util.task.DSData;
import com.ukefu.util.task.DSDataEvent;
import com.ukefu.util.task.ExcelImportProecess;
import com.ukefu.util.task.export.ExcelExporterProcess;
import com.ukefu.util.task.process.TopicProcess;
import com.ukefu.webim.service.cache.CacheHelper;
import com.ukefu.webim.service.repository.AiConfigRepository;
import com.ukefu.webim.service.repository.ChatMessageRepository;
import com.ukefu.webim.service.repository.KnowledgeTypeRepository;
import com.ukefu.webim.service.repository.MetadataRepository;
import com.ukefu.webim.service.repository.ReporterRepository;
import com.ukefu.webim.service.repository.SceneItemRepository;
import com.ukefu.webim.service.repository.SceneRepository;
import com.ukefu.webim.service.repository.SceneTypeRepository;
import com.ukefu.webim.service.repository.TopicRepository;
import com.ukefu.webim.service.repository.WordsTypeRepository;
import com.ukefu.webim.web.handler.Handler;
import com.ukefu.webim.web.model.AiConfig;
import com.ukefu.webim.web.model.KnowledgeType;
import com.ukefu.webim.web.model.MetadataTable;
import com.ukefu.webim.web.model.Scene;
import com.ukefu.webim.web.model.SceneItem;
import com.ukefu.webim.web.model.SceneType;
import com.ukefu.webim.web.model.Topic;
import com.ukefu.webim.web.model.UKeFuDic;
import com.ukefu.webim.web.model.Words;
import com.ukefu.webim.web.model.WordsType;

@Controller
@RequestMapping("/apps/xiaoe")
public class XiaoEController extends Handler{
	
	@Value("${web.upload-path}")
    private String path;
	
	@Value("${uk.im.server.port}")  
    private Integer port; 
	
	@Autowired
	private KnowledgeTypeRepository knowledgeTypeRes ;
	
	@Autowired
	private SceneTypeRepository sceneTypeRes ;
	
	@Autowired
	private WordsTypeRepository wordsTypeRes ;
	
	@Autowired
	private SceneRepository sceneRes ;
	
	@Autowired
	private SceneItemRepository sceneItemRes ;
	
	@Autowired
	private TopicRepository topicRes;
	
	@Autowired
	private AiConfigRepository aiConfigRes ; 

	@Autowired
	private ChatMessageRepository chatMessageRes;
	
	@Autowired
	private MetadataRepository metadataRes ;
	
	@Autowired
	private ReporterRepository reporterRes ;
	
    @RequestMapping("/index")
    @Menu(type = "xiaoe" , subtype = "xiaoe")
    public ModelAndView index(ModelMap map , HttpServletRequest request , @Valid String q , @Valid String type) throws IOException {
    	map.put("aiConfig", AiUtils.initAiConfig(super.getOrgi(request))) ;
    	return request(super.createAppsTempletResponse("/apps/business/xiaoe/index"));
    }
    
    @RequestMapping("history")
    @Menu(type = "xiaoe" , subtype = "history")
    public ModelAndView history(ModelMap map , HttpServletRequest request , @Valid String q , @Valid String type) throws IOException {
    	map.put("historyList", chatMessageRes.findByChatypeAndOrgi(UKDataContext.AiItemType.USERINPUT.toString(), super.getOrgi(request) , new PageRequest(super.getP(request), super.getPs(request) , Sort.Direction.DESC, "createtime"))) ;
    	return request(super.createAppsTempletResponse("/apps/business/xiaoe/chat/history"));
    }
    
    @RequestMapping("/config/save")
    @Menu(type = "setting" , subtype = "aiconfig" , admin= true)
    public ModelAndView aiconfig(ModelMap map , HttpServletRequest request , @Valid AiConfig aiConfig) {
    	AiConfig tempAiConfig = aiConfigRes.findByOrgi(super.getOrgi(request)) ;
    	if(tempAiConfig == null){
    		tempAiConfig = aiConfig;
    		aiConfig.setCreater(super.getUser(request).getId());
    	}else{
    		aiConfig.setCreater(super.getUser(request).getId());
    		aiConfig.setCreatetime(tempAiConfig.getCreatetime());
    		aiConfig.setOrgi(super.getOrgi(request));
    		tempAiConfig = aiConfig ;
    	}
    	tempAiConfig.setOrgi(super.getOrgi(request));
    	aiConfigRes.save(tempAiConfig) ;
    	
    	CacheHelper.getSystemCacheBean().put(UKDataContext.SYSTEM_CACHE_AI_CONFIG,tempAiConfig, super.getOrgi(request)) ;
    	
    	map.put("aiConfig", tempAiConfig) ;
        return request(super.createAppsTempletResponse("/apps/business/xiaoe/index"));
    }
    
    @RequestMapping("/chat")
    @Menu(type = "xiaoe" , subtype = "chat")
    public ModelAndView chat(ModelMap map , HttpServletRequest request , @Valid String q , @Valid String type) {
    	map.put("import", port) ;
    	map.put("appid", super.getOrgi(request)) ;
    	map.put("userid", super.getUser(request).getId()) ;
    	map.put("schema", request.getScheme()) ;
    	map.put("sessionid", super.getUser(request).getSessionid()) ;
    	
    	map.put("topicList",topicRes.getTopicByTop(true, super.getP(request),  super.getPs(request))) ;
    	
    	return request(super.createAppsTempletResponse("/apps/business/xiaoe/chat/index"));
    }
    
    @RequestMapping("/words")
    @Menu(type = "xiaoe" , subtype = "words")
    public ModelAndView words(ModelMap map , HttpServletRequest request , @Valid String q , @Valid String type) throws IOException {
    	List<WordsType> wordsTypeList = wordsTypeRes.findByOrgi(super.getOrgi(request))  ; 
    	map.put("wordsTypeList", wordsTypeList);
    	WordsType ktype = null ;
    	if(!StringUtils.isBlank(type)){
    		for(WordsType wordsType : wordsTypeList){
    			if(wordsType.getId().equals(type)){
    				ktype = wordsType ;
    				break ;
    			}
    		}
    	}
    	if(!StringUtils.isBlank(q)){
    		map.put("q", q) ;
     	}
    	File dicFile = null ;
    	if(ktype!=null){
    		map.put("curtype", ktype) ;
    		dicFile = new File(path , "dic/lex-"+ktype.getId()+".lex") ;
    		if(!dicFile.getParentFile().exists()){
    			dicFile.getParentFile().mkdirs();
    		}
    		if(!dicFile.exists()){
    			dicFile.createNewFile();
    		}
    	}else{
    		dicFile = new File(path , "dic/lex-"+UKDataContext.DEFAULT_TYPE+".lex") ;
    		if(!dicFile.getParentFile().exists()){
    			dicFile.getParentFile().mkdirs();
    		}
    		if(!dicFile.exists()){
    			dicFile.createNewFile();
    		}
    		
    	}
    	if(dicFile!=null && dicFile.exists()){
	    	List<Words> words = new ArrayList<Words>() ;
			for(String text : FileUtils.readLines(dicFile, "UTF-8")){
				if(!StringUtils.isBlank(text) && !text.startsWith("/")){
	    			String[] keys = text.split("/") ;
	    			words.add(new Words(keys[0] , keys.length >= 5 && !keys[4].equals("null") ? keys[4] : null , keys.length >= 4 &&  !keys[3].equals("null") ? keys[3] : null)) ;
				}
			}
			map.put("wordsList", words)  ;
    	}
    	return request(super.createAppsTempletResponse("/apps/business/xiaoe/words/index"));
    }
    
    @RequestMapping("/words/delete")
    @Menu(type = "xiaoe" , subtype = "wordsdelete")
    public ModelAndView wordsdelete(HttpServletRequest request ,@Valid String word , @Valid String type) throws IOException {
    	
    	File dicFile = null ;
    	if(type!=null){
    		WordsType wordsType = wordsTypeRes.findOne(type) ;
    		dicFile = new File(path , "dic/lex-"+wordsType.getId()+".lex") ;
    		if(!dicFile.getParentFile().exists()){
    			dicFile.getParentFile().mkdirs();
    		}
    		if(!dicFile.exists()){
    			dicFile.createNewFile();
    		}
    	}else{
    		dicFile = new File(path , "dic/lex-"+UKDataContext.DEFAULT_TYPE+".lex") ;
    		if(!dicFile.getParentFile().exists()){
    			dicFile.getParentFile().mkdirs();
    		}
    		if(!dicFile.exists()){
    			dicFile.createNewFile();
    		}
    		
    	}
    	if(dicFile!=null && dicFile.exists()){
	    	List<String> words = FileUtils.readLines(dicFile, "UTF-8") ;
			for(int i =0 ;i<words.size() ; ){
				String text = words.get(i) ;
				if(!StringUtils.isBlank(text)){
	    			if(text.substring(0, text.indexOf("/")>0?text.indexOf("/"):text.length()).equals(word)){
	    				words.remove(i) ;
	    				continue ;
	    			}
				}else{
					words.remove(i) ;
    				continue ;
				}
				i++ ;
			}
			FileUtils.writeLines(dicFile,"UTF-8" , words);
			/**
			 * 同时删除 词库里 的词条
			 */
			DicSegment.removeWord(word);
    	}
    	return request(super.createRequestPageTempletResponse("redirect:/apps/xiaoe/words.html"));
    }
    
    @RequestMapping("/words/type/add")
    @Menu(type = "xiaoe" , subtype = "wordstypeadd")
    public ModelAndView wordstypeadd(ModelMap map , HttpServletRequest request ) {
    	return request(super.createRequestPageTempletResponse("/apps/business/xiaoe/words/addtype"));
    }
    
    @RequestMapping("/words/type/save")
    @Menu(type = "xiaoe" , subtype = "wordstypesave")
    public ModelAndView wordstypesave(HttpServletRequest request ,@Valid WordsType type) {
    	int tempTypeCount = wordsTypeRes.countByNameAndOrgi(type.getName(), super.getOrgi(request)) ;
    	if(tempTypeCount == 0){
    		type.setOrgi(super.getOrgi(request));
    		type.setCreatetime(new Date());
    		type.setUpdatetime(new Date());
    		type.setCreater(super.getUser(request).getId());
    		wordsTypeRes.save(type) ;
    	}
    	return request(super.createRequestPageTempletResponse("redirect:/apps/xiaoe/words.html"));
    }
    
    @RequestMapping("/words/type/edit")
    @Menu(type = "xiaoe" , subtype = "wordstypeedit")
    public ModelAndView wordstypeedit(ModelMap map , HttpServletRequest request, @Valid String type ) {
    	map.put("wordsType", wordsTypeRes.findOne(type)) ;
    	return request(super.createRequestPageTempletResponse("/apps/business/xiaoe/words/edittype"));
    }
    
    @RequestMapping("/words/type/update")
    @Menu(type = "xiaoe" , subtype = "wordstypeupdate")
    public ModelAndView wordstypeupdate(HttpServletRequest request ,@Valid WordsType type) {
    	int tempTypeCount = wordsTypeRes.countByNameAndOrgi(type.getName(), super.getOrgi(request)) ;
    	if(tempTypeCount == 0){
    		WordsType temp = wordsTypeRes.findByIdAndOrgi(type.getId(), super.getOrgi(request)) ;
    		temp.setName(type.getName());
    		wordsTypeRes.save(temp) ;
    	}
    	return request(super.createRequestPageTempletResponse("redirect:/apps/xiaoe/words.html?type="+type.getId()));
    }
    
    @RequestMapping("/words/type/delete")
    @Menu(type = "xiaoe" , subtype = "wordsdelete")
    public ModelAndView wordstypedelete(HttpServletRequest request ,@Valid String id , @Valid String type) throws IOException {
    	File dicFile = null ;
    	if(type!=null){
    		WordsType wordsType = wordsTypeRes.findOne(type) ;
    		dicFile = new File(path , "dic/lex-"+wordsType.getId()+".lex") ;
    		if(!dicFile.getParentFile().exists()){
    			dicFile.getParentFile().mkdirs();
    		}
    		if(!dicFile.exists()){
    			dicFile.createNewFile();
    		}
    	}
    	if(dicFile.length() > 0){
    		
    		List<String> words = FileUtils.readLines(dicFile, "UTF-8") ;
			for(int i =0 ;i<words.size() ; ){
				String text = words.get(i) ;
				if(StringUtils.isBlank(text)){
					words.remove(i) ;
    				continue ;
				}
				i++ ;
			}
    		
	    	dicFile = new File(path , "dic/lex-"+UKDataContext.DEFAULT_TYPE+".lex") ;
			if(!dicFile.getParentFile().exists()){
				dicFile.getParentFile().mkdirs();
			}
			if(!dicFile.exists()){
				dicFile.createNewFile();
			}
			
			FileUtils.writeLines(dicFile,"UTF-8" , words , true);
    	}
    	return request(super.createRequestPageTempletResponse("redirect:/apps/xiaoe/words.html"));
    }
    

    @RequestMapping("/words/add")
    @Menu(type = "xiaoe" , subtype = "wordsadd")
    public ModelAndView wordsadd(ModelMap map , HttpServletRequest request , @Valid String type) {
    	map.put("type", type);
    	return request(super.createRequestPageTempletResponse("/apps/business/xiaoe/words/add"));
    }
    
    @RequestMapping("/words/save")
    @Menu(type = "xiaoe" , subtype = "knowledgesave")
    public ModelAndView wordssave(HttpServletRequest request ,@Valid Words words , @Valid String type) throws IOException {
    	File dicFile = null ;
    	if(!StringUtils.isBlank(type)){
    		WordsType wordsType = wordsTypeRes.findOne(type) ;
    		dicFile = new File(path , "dic/lex-"+wordsType.getId()+".lex") ;
    		if(!dicFile.getParentFile().exists()){
    			dicFile.getParentFile().mkdirs();
    		}
    		if(!dicFile.exists()){
    			dicFile.createNewFile();
    		}
    	}else{
    		dicFile = new File(path , "dic/lex-"+UKDataContext.DEFAULT_TYPE+".lex") ;
    		if(!dicFile.getParentFile().exists()){
    			dicFile.getParentFile().mkdirs();
    		}
    		if(!dicFile.exists()){
    			dicFile.createNewFile();
    		}
    	}
    	if(dicFile!=null && dicFile.exists()){
    		List<String> lines = new ArrayList<String>();
    		String keyword  = null , superordinate = null ;
    		if(!StringUtil.isBlank(words.getKeyword())){
    			keyword = words.getKeyword().split("[ ,，:;]")[0] ;
    		}
    		if(!StringUtil.isBlank(words.getSuperordinate())){
    			superordinate = words.getSuperordinate().split("[ ,，:;]")[0] ;
    		}
    		StringBuffer strb = new StringBuffer();
    		
    		strb.append(keyword).append("/uckefu/null/") ;
    		int i= 0 ;
    		for(String word : words.getContent().split("[, ，:；;\\n\t ]")){
    			if(!StringUtils.isBlank(word)){
    				if(i++ > 0){
    					strb.append(",");
    				}
    				strb.append(word) ;
    				lines.add(word+"/uckefu/null/null/"+superordinate) ;
    			}
    		}
    		if(!StringUtils.isBlank(superordinate)){
    			lines.add(superordinate+"/uckefu/null/null/"+superordinate) ;
    		}
    		strb.append("/").append(superordinate) ;
    		
    		lines.add(strb.toString()) ;
    		FileUtils.writeLines(dicFile, "UTF-8" , lines, true);
    	}
    	return request(super.createRequestPageTempletResponse("redirect:/apps/xiaoe/words.html"+(!StringUtils.isBlank(type) ? "?type="+type : "")));
    }
    
    
    @RequestMapping("/words/batadd")
    @Menu(type = "xiaoe" , subtype = "wordsbatadd")
    public ModelAndView wordsbatadd(ModelMap map , HttpServletRequest request , @Valid String type) {
    	map.put("type", type);
    	return request(super.createRequestPageTempletResponse("/apps/business/xiaoe/words/batadd"));
    }
    
    @RequestMapping("/words/batsave")
    @Menu(type = "xiaoe" , subtype = "knowledgebatsave")
    public ModelAndView wordsbatsave(HttpServletRequest request ,@Valid Words words , @Valid String type) throws IOException {
    	File dicFile = null ;
    	if(!StringUtils.isBlank(type)){
    		WordsType wordsType = wordsTypeRes.findOne(type) ;
    		dicFile = new File(path , "dic/lex-"+wordsType.getId()+".lex") ;
    		if(!dicFile.getParentFile().exists()){
    			dicFile.getParentFile().mkdirs();
    		}
    		if(!dicFile.exists()){
    			dicFile.createNewFile();
    		}
    	}else{
    		dicFile = new File(path , "dic/lex-"+UKDataContext.DEFAULT_TYPE+".lex") ;
    		if(!dicFile.getParentFile().exists()){
    			dicFile.getParentFile().mkdirs();
    		}
    		if(!dicFile.exists()){
    			dicFile.createNewFile();
    		}
    	}
    	List<String> lines = new ArrayList<String>();
    	if(!StringUtils.isBlank(words.getContent())){
    		for(String word : words.getContent().split("[, ，:；;\\n\t ]")){
    			if(!StringUtils.isBlank(word)){
    				lines.add(word+"/uckefu/null/null") ;
    			}
    		}
    		if(dicFile!=null && dicFile.exists()){
        		FileUtils.writeLines(dicFile , "UTF-8",lines, true);
        	}
    	}
    	
    	return request(super.createRequestPageTempletResponse("redirect:/apps/xiaoe/words.html"+(!StringUtils.isBlank(type) ? "?type="+type : "")));
    }
    
    @RequestMapping("/words/reload")
    @Menu(type = "xiaoe" , subtype = "wordsreload")
    public ModelAndView wordsreload(ModelMap map , HttpServletRequest request , @Valid String type) throws IOException {
    	DicSegment.loadDic(new File(path , "dic").getAbsolutePath());
    	return request(super.createRequestPageTempletResponse("redirect:/apps/xiaoe/words.html"+(!StringUtils.isBlank(type) ? "?type="+type : "")));
    }
    
    
    
    @RequestMapping("/knowledge")
    @Menu(type = "xiaoe" , subtype = "knowledge")
    public ModelAndView knowledge(ModelMap map , HttpServletRequest request , @Valid String q , @Valid String type) {
    	List<KnowledgeType> knowledgeTypeList = knowledgeTypeRes.findByOrgi(super.getOrgi(request))  ; 
    	map.put("knowledgeTypeList", knowledgeTypeList);
    	KnowledgeType ktype = null ;
    	if(!StringUtils.isBlank(type)){
    		for(KnowledgeType knowledgeType : knowledgeTypeList){
    			if(knowledgeType.getId().equals(type)){
    				ktype = knowledgeType ;
    				break ;
    			}
    		}
    	}
    	if(!StringUtils.isBlank(q)){
    		map.put("q", q) ;
     	}
    	if(ktype!=null){
    		map.put("curtype", ktype) ;
    		map.put("topicList", topicRes.getTopicByCate(ktype.getId(), q, super.getP(request), super.getPs(request)))  ;
    	}else{
    		map.put("topicList", topicRes.getTopicByCate(UKDataContext.DEFAULT_TYPE, q, super.getP(request), super.getPs(request)))  ;
    	}
    	
    	return request(super.createAppsTempletResponse("/apps/business/xiaoe/knowledge/index"));
    }
    
    @RequestMapping("/knowledge/add")
    @Menu(type = "xiaoe" , subtype = "knowledgeadd")
    public ModelAndView knowledgeadd(ModelMap map , HttpServletRequest request , @Valid String type) {
    	map.put("type", type);
    	return request(super.createRequestPageTempletResponse("/apps/business/xiaoe/knowledge/add"));
    }
    
    @RequestMapping("/knowledge/save")
    @Menu(type = "xiaoe" , subtype = "knowledgesave")
    public ModelAndView knowledgesave(HttpServletRequest request ,@Valid Topic topic , @Valid String type) {
    	if(!StringUtils.isBlank(topic.getTitle())){
    		if(!StringUtils.isBlank(type)){
    			topic.setCate(type);
    		}else{
    			topic.setCate(UKDataContext.DEFAULT_TYPE);
    		}
    		topic.setOrgi(super.getOrgi(request));
    		topicRes.save(topic) ;
    	}
    	return request(super.createRequestPageTempletResponse("redirect:/apps/xiaoe/knowledge.html"+(!StringUtils.isBlank(type) ? "?type="+type : "")));
    }
    
    @RequestMapping("/knowledge/edit")
    @Menu(type = "xiaoe" , subtype = "knowledgeedit")
    public ModelAndView knowledgeedit(ModelMap map , HttpServletRequest request , @Valid String id , @Valid String type) {
    	map.put("type", type);
    	if(!StringUtils.isBlank(id)){
    		map.put("topic", topicRes.findOne(id)) ;
    	}
    	return request(super.createRequestPageTempletResponse("/apps/business/xiaoe/knowledge/edit"));
    }
    
    @RequestMapping("/knowledge/update")
    @Menu(type = "xiaoe" , subtype = "knowledgeupdate")
    public ModelAndView knowledgeupdate(HttpServletRequest request ,@Valid Topic topic , @Valid String type) {
    	Topic temp = topicRes.findOne(topic.getId()) ;
    	if(!StringUtils.isBlank(topic.getTitle())){
    		if(!StringUtils.isBlank(type)){
    			topic.setCate(type);
    		}else{
    			topic.setCate(UKDataContext.DEFAULT_TYPE);
    		}
    		topic.setCreater(temp.getCreater());
    		topic.setCreatetime(temp.getCreatetime());
    		topic.setOrgi(super.getOrgi(request));
    		topicRes.save(topic) ;
    	}
    	return request(super.createRequestPageTempletResponse("redirect:/apps/xiaoe/knowledge.html"+(!StringUtils.isBlank(type) ? "?type="+type : "")));
    }
    
    @RequestMapping("/knowledge/delete")
    @Menu(type = "xiaoe" , subtype = "knowledgedelete")
    public ModelAndView knowledgedelete(HttpServletRequest request ,@Valid String id , @Valid String type) {
    	if(!StringUtils.isBlank(id)){
    		topicRes.delete(topicRes.findOne(id));
    	}
    	return request(super.createRequestPageTempletResponse("redirect:/apps/xiaoe/knowledge.html"+(!StringUtils.isBlank(type) ? "?type="+type : "")));
    }
    
    @RequestMapping("/knowledge/type/add")
    @Menu(type = "xiaoe" , subtype = "knowledgetypeadd")
    public ModelAndView knowledgetypeadd(ModelMap map , HttpServletRequest request ) {
    	return request(super.createRequestPageTempletResponse("/apps/business/xiaoe/knowledge/addtype"));
    }
    
    @RequestMapping("/knowledge/type/save")
    @Menu(type = "xiaoe" , subtype = "knowledgetypesave")
    public ModelAndView knowledgetypesave(HttpServletRequest request ,@Valid KnowledgeType type) {
    	int tempTypeCount = knowledgeTypeRes.countByNameAndOrgi(type.getName(), super.getOrgi(request)) ;
    	if(tempTypeCount == 0){
    		type.setOrgi(super.getOrgi(request));
    		type.setCreatetime(new Date());
    		type.setUpdatetime(new Date());
    		type.setCreater(super.getUser(request).getId());
    		knowledgeTypeRes.save(type) ;
    	}
    	return request(super.createRequestPageTempletResponse("redirect:/apps/xiaoe/knowledge.html"));
    }
    
    @RequestMapping("/knowledge/type/edit")
    @Menu(type = "xiaoe" , subtype = "knowledgetypeedit")
    public ModelAndView knowledgetypeedit(ModelMap map , HttpServletRequest request, @Valid String type ) {
    	map.put("knowledgeType", knowledgeTypeRes.findOne(type)) ;
    	return request(super.createRequestPageTempletResponse("/apps/business/xiaoe/knowledge/edittype"));
    }
    
    @RequestMapping("/knowledge/type/update")
    @Menu(type = "xiaoe" , subtype = "knowledgetypeupdate")
    public ModelAndView knowledgetypeupdate(HttpServletRequest request ,@Valid KnowledgeType type) {
    	int tempTypeCount = knowledgeTypeRes.countByNameAndOrgi(type.getName(), super.getOrgi(request)) ;
    	if(tempTypeCount == 0){
    		KnowledgeType temp = knowledgeTypeRes.findByIdAndOrgi(type.getId(), super.getOrgi(request)) ;
    		temp.setName(type.getName());
    		knowledgeTypeRes.save(temp) ;
    	}
    	return request(super.createRequestPageTempletResponse("redirect:/apps/xiaoe/knowledge.html?type="+type.getId()));
    }
    
    @RequestMapping("/knowledge/type/delete")
    @Menu(type = "xiaoe" , subtype = "knowledgedelete")
    public ModelAndView knowledgetypedelete(HttpServletRequest request ,@Valid String id , @Valid String type) {
    	Page<Topic> page = topicRes.getTopicByCate(type, null, super.getP(request), super.getPs(request)) ;
    	String msg = null ;
    	if(page.getTotalElements() == 0){
	    	if(!StringUtils.isBlank(id)){
	    		knowledgeTypeRes.delete(id);
	    	}
    	}else{
    		msg = "notempty" ;
    	}
    	return request(super.createRequestPageTempletResponse("redirect:/apps/xiaoe/knowledge.html"+(msg!=null ? "?msg=notempty" : "")));
    }
    
    @RequestMapping("/knowledge/imp")
    @Menu(type = "xiaoe" , subtype = "knowledge")
    public ModelAndView imp(ModelMap map , HttpServletRequest request , @Valid String type) {
    	map.addAttribute("type", type) ;
        return request(super.createRequestPageTempletResponse("/apps/business/xiaoe/knowledge/imp"));
    }
    
    @RequestMapping("/knowledge/impsave")
    @Menu(type = "xiaoe" , subtype = "knowledge")
    public ModelAndView impsave(ModelMap map , HttpServletRequest request , @RequestParam(value = "cusfile", required = false) MultipartFile cusfile , @Valid String type) throws IOException {
    	DSDataEvent event = new DSDataEvent();
    	String fileName = "xiaoe/"+UKTools.getUUID()+cusfile.getOriginalFilename().substring(cusfile.getOriginalFilename().lastIndexOf(".")) ;
    	File excelFile = new File(path , fileName) ;
    	if(!excelFile.getParentFile().exists()){
    		excelFile.getParentFile().mkdirs() ;
    	}
    	MetadataTable table = metadataRes.findByTablename("uk_xiaoe_topic") ;
    	if(table!=null){
	    	FileUtils.writeByteArrayToFile(new File(path , fileName), cusfile.getBytes());
	    	event.setDSData(new DSData(table,excelFile , cusfile.getContentType(), super.getUser(request)));
	    	event.getDSData().setClazz(Topic.class);
	    	event.setOrgi(super.getOrgi(request));
	    	if(!StringUtils.isBlank(type)){
	    		event.getValues().put("cate", type) ;
	    	}else{
	    		event.getValues().put("cate", UKDataContext.DEFAULT_TYPE) ;
	    	}
	    	event.getValues().put("creater", super.getUser(request).getId()) ;
	    	event.getDSData().setProcess(new TopicProcess(topicRes));
	    	reporterRes.save(event.getDSData().getReport()) ;
	    	new ExcelImportProecess(event).process() ;		//启动导入任务
    	}
    	
    	return request(super.createRequestPageTempletResponse("redirect:/apps/xiaoe/knowledge.html"));
    }
    
    @RequestMapping("/knowledge/expids")
    @Menu(type = "xiaoe" , subtype = "knowledge")
    public void expids(ModelMap map , HttpServletRequest request , HttpServletResponse response , @Valid String[] ids) throws IOException {
    	if(ids!=null && ids.length > 0){
    		Iterable<Topic> topicList = topicRes.findAll(Arrays.asList(ids)) ;
    		MetadataTable table = metadataRes.findByTablename("uk_xiaoe_topic") ;
    		List<Map<String,Object>> values = new ArrayList<Map<String,Object>>();
    		for(Topic topic : topicList){
    			values.add(UKTools.transBean2Map(topic)) ;
    		}
    		
    		response.setHeader("content-disposition", "attachment;filename=UCKeFu-Contacts-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls");  
    		if(table!=null){
    			ExcelExporterProcess excelProcess = new ExcelExporterProcess( values, table, response.getOutputStream()) ;
    			excelProcess.process();
    		}
    	}
    	
        return ;
    }
    
    @RequestMapping("/knowledge/expall")
    @Menu(type = "xiaoe" , subtype = "knowledge")
    public void expall(ModelMap map , HttpServletRequest request , HttpServletResponse response,@Valid String type) throws IOException {
    	Iterable<Topic> topicList = topicRes.getTopicByOrgi(super.getOrgi(request) , !StringUtils.isBlank(type) ? type : UKDataContext.DEFAULT_TYPE , null) ;
    	
    	MetadataTable table = metadataRes.findByTablename("uk_xiaoe_topic") ;
		List<Map<String,Object>> values = new ArrayList<Map<String,Object>>();
		for(Topic topic : topicList){
			values.add(UKTools.transBean2Map(topic)) ;
		}
		
		response.setHeader("content-disposition", "attachment;filename=UCKeFu-XiaoE-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls");  
		
		if(table!=null){
			ExcelExporterProcess excelProcess = new ExcelExporterProcess( values, table, response.getOutputStream()) ;
			excelProcess.process();
		}
        return ;
    }
    
    @RequestMapping("/knowledge/expsearch")
    @Menu(type = "xiaoe" , subtype = "knowledge")
    public void expall(ModelMap map , HttpServletRequest request , HttpServletResponse response , @Valid String q , @Valid String type) throws IOException {
    	
    	Iterable<Topic> topicList = topicRes.getTopicByOrgi(super.getOrgi(request) , type , q) ;
    	
    	MetadataTable table = metadataRes.findByTablename("uk_xiaoe_topic") ;
		List<Map<String,Object>> values = new ArrayList<Map<String,Object>>();
		for(Topic topic : topicList){
			values.add(UKTools.transBean2Map(topic)) ;
		}
		
		response.setHeader("content-disposition", "attachment;filename=UCKeFu-XiaoE-"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls");  
		
		if(table!=null){
			ExcelExporterProcess excelProcess = new ExcelExporterProcess( values, table, response.getOutputStream()) ;
			excelProcess.process();
		}
        return ;
    }
    
    
    
    @RequestMapping("/scene")
    @Menu(type = "xiaoe" , subtype = "scene")
    public ModelAndView scene(ModelMap map , HttpServletRequest request , @Valid String q , @Valid String type) {
    	List<SceneType> sceneTypeList = sceneTypeRes.findByOrgi(super.getOrgi(request))  ; 
    	map.put("sceneTypeList", sceneTypeList);
    	SceneType stype = null ;
    	if(!StringUtils.isBlank(type)){
    		for(SceneType sceneType : sceneTypeList){
    			if(sceneType.getId().equals(type)){
    				stype = sceneType ;
    				break ;
    			}
    		}
    	}
    	if(!StringUtils.isBlank(q)){
    		map.put("q", q) ;
     	}
    	if(stype!=null){
    		map.put("curtype", stype) ;
    		map.put("sceneList", sceneRes.findByOrgiAndCate(super.getOrgi(request) , stype.getId(),new PageRequest(super.getP(request), super.getPs(request))))  ;
    	}else{
    		map.put("sceneList", sceneRes.findByOrgiAndCate(super.getOrgi(request) , UKDataContext.DEFAULT_TYPE,new PageRequest(super.getP(request), super.getPs(request))))  ;
    	}
    	
    	return request(super.createAppsTempletResponse("/apps/business/xiaoe/scene/index"));
    }
    
    @RequestMapping("/scene/add")
    @Menu(type = "xiaoe" , subtype = "sceneadd")
    public ModelAndView sceneadd(ModelMap map , HttpServletRequest request , @Valid String type) {
    	map.put("type", type);
    	map.put("inputConList", UKeFuDic.getInstance().getSysDic("com.dic.xiaoe.input"));
    	map.put("outputConList", UKeFuDic.getInstance().getSysDic("com.dic.xiaoe.output"));
    	
    	return request(super.createRequestPageTempletResponse("/apps/business/xiaoe/scene/add"));
    }
    
    @RequestMapping("/scene/save")
    @Menu(type = "xiaoe" , subtype = "scenesave")
    public ModelAndView scenesave(HttpServletRequest request ,@Valid Scene scene , @Valid String[] userinput, @Valid String[] aireply , @Valid String type) throws IOException, JcsegException {
    	if(!StringUtils.isBlank(scene.getTitle())){
    		if(!StringUtils.isBlank(type)){
    			scene.setCate(type);
    		}else{
    			scene.setCate(UKDataContext.DEFAULT_TYPE);
    		}
    		if(userinput!=null && userinput.length >0){
    			scene.setUserinput(userinput[0]);
    		}
    		if(aireply!=null && aireply.length >0){
    			scene.setAireply(aireply[0]);
    		}
    		scene.setOrgi(super.getOrgi(request));
    		scene.setCreater(super.getUser(request).getId());
    		scene.setCreatetime(new Date());
    		
    		if(userinput!=null && userinput.length >0){
    			List<SceneItem> userInputItems = new ArrayList<SceneItem>();
    			for(int i=0 ; i<userinput.length ; i++){
    				String user = userinput[i] ;
    				if(!StringUtils.isBlank(user)){
	    				SceneItem item = new SceneItem();
	    				item.setContent(user);
	    				item.setOrgi(super.getOrgi(request));
	    				item.setCreater(super.getUser(request).getId());
	    				item.setInx(i);
	    				item.setAllowask(scene.isAllowask());
	    				item.setReplaytype(scene.getReplaytype());
	    				item.setSceneid(scene.getId());
	    				item.setItemtype(UKDataContext.AiItemType.USERINPUT.toString());
	    				userInputItems.add(item) ;
    				}
    			}
    			sceneItemRes.save(userInputItems) ;
    		}
    		
    		if(aireply!=null && aireply.length >0){
    			List<SceneItem> aiReplyItems = new ArrayList<SceneItem>();
    			for(int i=0 ; i<aireply.length ; i++){
    				String air = aireply[i] ;
    				if(!StringUtils.isBlank(air)){
	    				SceneItem item = new SceneItem();
	    				item.setContent(air);
	    				item.setOrgi(super.getOrgi(request));
	    				item.setCreater(super.getUser(request).getId());
	    				
	    				item.setAllowask(scene.isAllowask());
	    				item.setReplaytype(scene.getReplaytype());
	    				
	    				item.setInx(i);
	    				item.setSceneid(scene.getId());
	    				item.setItemtype(UKDataContext.AiItemType.AIREPLY.toString());
	    				aiReplyItems.add(item) ;
    				}
    			}
    			sceneItemRes.save(aiReplyItems) ;
    		}
    		
    		sceneRes.save(scene) ;
    		/**
    		 * 重新初始化 AI对话
    		 */
    		AiUtils.init(UKDataContext.SYSTEM_ORGI) ;
    	}
    	return request(super.createRequestPageTempletResponse("redirect:/apps/xiaoe/scene.html"+(!StringUtils.isBlank(type) ? "?type="+type : "")));
    }
    
    @RequestMapping("/scene/edit")
    @Menu(type = "xiaoe" , subtype = "sceneedit")
    public ModelAndView sceneedit(ModelMap map , HttpServletRequest request , @Valid String id , @Valid String type) {
    	map.put("type", type);
    	map.put("inputConList", UKeFuDic.getInstance().getSysDic("com.dic.xiaoe.input"));
    	map.put("outputConList", UKeFuDic.getInstance().getSysDic("com.dic.xiaoe.output"));
    	
    	map.put("scene", sceneRes.findOne(id)) ;
    	map.put("sceneItemList", sceneItemRes.findByOrgiAndSceneid(super.getOrgi(request), id)) ;
    	
    	return request(super.createRequestPageTempletResponse("/apps/business/xiaoe/scene/edit"));
    }
    
    @RequestMapping("/scene/update")
    @Menu(type = "xiaoe" , subtype = "sceneupdate")
    public ModelAndView sceneupdate(HttpServletRequest request ,@Valid Scene scene , @Valid String[] userinput, @Valid String[] aireply , @Valid String type) throws IOException, JcsegException {
    	if(!StringUtils.isBlank(scene.getTitle())){
    		Scene temp = sceneRes.findOne(scene.getId()) ;
    		if(!StringUtils.isBlank(type)){
    			scene.setCate(type);
    		}else{
    			scene.setCate(UKDataContext.DEFAULT_TYPE);
    		}
    		if(userinput!=null && userinput.length >0){
    			scene.setUserinput(userinput[0]);
    		}
    		if(aireply!=null && aireply.length >0){
    			scene.setAireply(aireply[0]);
    		}
    		scene.setCreater(temp.getCreater());
    		scene.setCreatetime(temp.getCreatetime());
    		scene.setOrgi(super.getOrgi(request));
    		
    		sceneItemRes.delete(sceneItemRes.findByOrgiAndSceneid(super.getOrgi(request), scene.getId()));
    		
    		if(userinput!=null && userinput.length >0){
    			List<SceneItem> userInputItems = new ArrayList<SceneItem>();
    			for(int i=0 ; i<userinput.length ; i++){
    				String user = userinput[i] ;
    				SceneItem item = new SceneItem();
    				item.setContent(user);
    				item.setOrgi(super.getOrgi(request));
    				item.setCreater(super.getUser(request).getId());
    				item.setInx(i);
    				item.setSceneid(scene.getId());
    				item.setItemtype(UKDataContext.AiItemType.USERINPUT.toString());
    				userInputItems.add(item) ;
    			}
    			sceneItemRes.save(userInputItems) ;
    		}
    		
    		if(aireply!=null && aireply.length >0){
    			List<SceneItem> aiReplyItems = new ArrayList<SceneItem>();
    			for(int i=0 ; i<aireply.length ; i++){
    				String air = aireply[i] ;
    				SceneItem item = new SceneItem();
    				item.setContent(air);
    				item.setOrgi(super.getOrgi(request));
    				item.setCreater(super.getUser(request).getId());
    				item.setInx(i);
    				item.setSceneid(scene.getId());
    				item.setItemtype(UKDataContext.AiItemType.AIREPLY.toString());
    				aiReplyItems.add(item) ;
    			}
    			sceneItemRes.save(aiReplyItems) ;
    		}
    		
    		sceneRes.save(scene) ;
    		
    		/**
    		 * 重新初始化 AI对话
    		 */
    		AiUtils.init(UKDataContext.SYSTEM_ORGI) ;
    	}
    	return request(super.createRequestPageTempletResponse("redirect:/apps/xiaoe/scene.html"+(!StringUtils.isBlank(type) ? "?type="+type : "")));
    }
    
    
    @RequestMapping("/scene/delete")
    @Menu(type = "xiaoe" , subtype = "scenedelete")
    public ModelAndView scenedelete(HttpServletRequest request ,@Valid String id , @Valid String type) throws IOException, JcsegException {
    	if(!StringUtils.isBlank(id)){
    		sceneRes.delete(id);
    		sceneItemRes.delete(sceneItemRes.findByOrgiAndSceneid(super.getOrgi(request), id));
    		/**
    		 * 重新初始化 AI对话
    		 */
    		AiUtils.init(UKDataContext.SYSTEM_ORGI) ;
    	}
    	return request(super.createRequestPageTempletResponse("redirect:/apps/xiaoe/scene.html"+(!StringUtils.isBlank(type) ? "?type="+type : "")));
    }
    
    @RequestMapping("/scene/type/add")
    @Menu(type = "xiaoe" , subtype = "scenetypeadd")
    public ModelAndView scenetypeadd(ModelMap map , HttpServletRequest request ) {
    	return request(super.createRequestPageTempletResponse("/apps/business/xiaoe/scene/addtype"));
    }
    
    @RequestMapping("/scene/type/save")
    @Menu(type = "xiaoe" , subtype = "scenetypesave")
    public ModelAndView scenetypesave(HttpServletRequest request ,@Valid SceneType type) {
    	int tempTypeCount = sceneTypeRes.countByNameAndOrgi(type.getName(), super.getOrgi(request)) ;
    	if(tempTypeCount == 0){
    		type.setOrgi(super.getOrgi(request));
    		type.setCreatetime(new Date());
    		type.setUpdatetime(new Date());
    		type.setCreater(super.getUser(request).getId());
    		sceneTypeRes.save(type) ;
    	}
    	return request(super.createRequestPageTempletResponse("redirect:/apps/xiaoe/scene.html"));
    }
    
    @RequestMapping("/scene/type/edit")
    @Menu(type = "xiaoe" , subtype = "scenetypeedit")
    public ModelAndView scenetypeedit(ModelMap map , HttpServletRequest request, @Valid String type ) {
    	map.put("sceneType", sceneTypeRes.findOne(type)) ;
    	return request(super.createRequestPageTempletResponse("/apps/business/xiaoe/scene/edittype"));
    }
    
    @RequestMapping("/scene/type/update")
    @Menu(type = "xiaoe" , subtype = "scenetypeupdate")
    public ModelAndView scenetypeupdate(HttpServletRequest request ,@Valid SceneType type) {
    	int tempTypeCount = sceneTypeRes.countByNameAndOrgi(type.getName(), super.getOrgi(request)) ;
    	if(tempTypeCount == 0){
    		SceneType temp = sceneTypeRes.findByIdAndOrgi(type.getId(), super.getOrgi(request)) ;
    		temp.setName(type.getName());
    		sceneTypeRes.save(temp) ;
    	}
    	return request(super.createRequestPageTempletResponse("redirect:/apps/xiaoe/scene.html?type="+type.getId()));
    }
    
    @RequestMapping("/scene/type/delete")
    @Menu(type = "xiaoe" , subtype = "scenedelete")
    public ModelAndView scenetypedelete(HttpServletRequest request ,@Valid String id , @Valid String type) {
    	Page<Topic> page = topicRes.getTopicByCate(type, null, super.getP(request), super.getPs(request)) ;
    	String msg = null ;
    	if(page.getTotalElements() == 0){
	    	if(!StringUtils.isBlank(id)){
	    		sceneTypeRes.delete(id);
	    	}
    	}else{
    		msg = "notempty" ;
    	}
    	return request(super.createRequestPageTempletResponse("redirect:/apps/xiaoe/scene.html"+(msg!=null ? "?msg=notempty" : "")));
    }
    
}